package middleware

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"gitee.com/huangxinbo/xcas/internal/asynq_handle_routes"
	"gitee.com/huangxinbo/xcas/pkg/i18n"
	"gitee.com/huangxinbo/xcas/pkg/logger"
	"github.com/google/uuid"
	"github.com/hibiken/asynq"
	"go.uber.org/zap"
)

type Middleware struct {
	Logger *logger.Logger
	I18n   *i18n.I18n
}

func NewMiddleware(logger *logger.Logger, i18n *i18n.I18n) *Middleware {
	return &Middleware{
		Logger: logger,
		I18n:   i18n,
	}
}

func (m *Middleware) Middleware(h asynq.Handler) asynq.Handler {
	return asynq.HandlerFunc(func(ctx context.Context, t *asynq.Task) error {
		start := time.Now()
		type CombinedPayload struct {
			Common asynq_handle_routes.RouteCommonPayload `json:"common"`
			Data   map[string]interface{}                 `json:"data"`
		}
		var p CombinedPayload
		if err := json.Unmarshal(t.Payload(), &p); err != nil {
			return fmt.Errorf("json.Unmarshal failed: %v: %w", err, asynq.SkipRetry)
		}

		m.I18n.Locale = p.Common.Language
		if p.Common.XRequestId == "" {
			m.Logger.XRequestId = uuid.New().String()
		}
		m.Logger.XRequestId = p.Common.XRequestId

		// 调用下一个处理器
		err := h.ProcessTask(ctx, t)

		// record save to database
		if err != nil {
			m.Logger.Error("task processed record failure", zap.String("type", t.Type()), zap.Error(err), zap.Duration("duration", time.Since(start)))
		} else {
			m.Logger.Info("task processed record success", zap.String("type", t.Type()), zap.Duration("duration", time.Since(start)))
		}

		return err
	})
}
